Skip to content

Conversation

@niko-exo
Copy link

@niko-exo niko-exo commented Jan 12, 2026

ref: https://app.clickup.com/t/86b82fa34

86b82fa34 - feat: add url fragment linking to tabs on edit sponsor page

Changelog

  • Add helper functions to handle the relationship between tabs and the url fragment.
  • Add react hook to listen for every fragment change.
  • Update fragment on every tab change.
  • Set default page on the tab general.
  • Set that if an user enters some random fragment, it will be redirected to the general tab.

Links

86b82fa34 - Add TAB deep-linking using URL fragment

Evidence

2026-01-12_09-56-27.mp4

Summary by CodeRabbit

  • New Features
    • Tabs on the sponsors page now use URL hash fragments so each tab can be directly linked or bookmarked.
    • Tab selection stays synchronized with the browser URL (updates when the hash changes and when users switch tabs), improving navigation and shareability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 12, 2026

📝 Walkthrough

Walkthrough

The edit sponsor page switches tab state to URL hash fragments. Added mapping and helpers to convert between tab indices and hash fragments, initialize selected tab from the hash, and a useEffect to keep state synchronized with window.location.hash; tab changes update the URL hash.

Changes

Cohort / File(s) Summary
Tab URL Persistence
src/pages/sponsors/edit-sponsor-page.js
Added tabsToFragmentMap and helpers getFragmentFromValue() / getTabFromUrlFragment(). Replaced previous pathname-based initial-tab logic with URL-hash initialization. Added useEffect to resync on window.location.hash changes. Updated tab change handler to set window.location.hash.

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant PageComponent
    participant TabState

    Note over Browser,PageComponent: Initial Load
    Browser->>PageComponent: load with URL hash
    PageComponent->>Browser: read window.location.hash
    PageComponent->>PageComponent: getTabFromUrlFragment()
    PageComponent->>TabState: initialize selectedTab
    TabState-->>PageComponent: state set

    Note over Browser,PageComponent: User selects tab
    Browser->>PageComponent: user clicks tab
    PageComponent->>PageComponent: onTabChange -> getFragmentFromValue()
    PageComponent->>Browser: set window.location.hash
    PageComponent->>TabState: update selectedTab

    Note over Browser,PageComponent: External hash change
    Browser->>PageComponent: window.location.hash changes
    PageComponent->>PageComponent: useEffect triggers
    PageComponent->>TabState: resync selectedTab
    TabState-->>PageComponent: state updated
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐇🌿 I hopped through tabs and left a trail,
Hash-fragment breadcrumbs without fail.
Bookmark a view, return with cheer,
The sponsor tabs are always near!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding URL fragment linking to tabs on the edit sponsor page, which aligns with the core functionality introduced in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
src/pages/sponsors/edit-sponsor-page.js (1)

49-58: Consider using an object map for explicit tab-to-fragment mapping.

An index-based array introduces tight coupling where the order must exactly match the SPONSOR_TABS enum values. An object map would be more explicit and resilient to future changes.

Example refactor using object map
import { SPONSOR_TABS } from "../../utils/constants";

const tabsToFragmentMap = {
  [SPONSOR_TABS.GENERAL]: "general",
  [SPONSOR_TABS.USERS]: "users",
  [SPONSOR_TABS.PAGES]: "pages",
  [SPONSOR_TABS.MEDIA_UPLOADS]: "media_uploads",
  [SPONSOR_TABS.FORMS]: "forms",
  [SPONSOR_TABS.CART]: "cart",
  [SPONSOR_TABS.PURCHASES]: "purchases",
  [SPONSOR_TABS.BADGE_SCANS]: "badge_scans"
};

const getFragmentFromValue = (tabValue) => tabsToFragmentMap[tabValue] ?? "general";

const getTabFromUrlFragment = () => {
  const fragment = window.location.hash.replace("#", "");
  const entry = Object.entries(tabsToFragmentMap).find(([, frag]) => frag === fragment);
  return entry ? Number(entry[0]) : SPONSOR_TABS.GENERAL;
};

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22f0d4b and 9c4adf3.

📒 Files selected for processing (1)
  • src/pages/sponsors/edit-sponsor-page.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: build
  • GitHub Check: build
  • GitHub Check: build
  • GitHub Check: build
  • GitHub Check: build
  • GitHub Check: build
🔇 Additional comments (1)
src/pages/sponsors/edit-sponsor-page.js (1)

126-129: No issue to address.

The SPONSOR_TABS enum values (0-7) are intentionally aligned with the tabsToFragmentMap array indices. The handler correctly uses the tab index to look up the corresponding fragment string. The code works as designed.

Likely an incorrect or invalid review comment.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @src/pages/sponsors/edit-sponsor-page.js:
- Around line 116-118: The useEffect using window.location.hash in the
dependency array won't re-run on hash changes; replace it with a hashchange
event listener: in the effect that currently calls
setSelectedTab(getTabFromUrlFragment()), register
window.addEventListener('hashchange', handler) where handler calls
setSelectedTab(getTabFromUrlFragment()), call the handler once on mount to
initialize, and remove the listener in the cleanup; remove window.location.hash
from the dependency array (use []).
🧹 Nitpick comments (1)
src/pages/sponsors/edit-sponsor-page.js (1)

46-64: Helper functions look good, consider consolidating the tab definition.

The mapping and helper functions are well-structured. The fallback to index 0 for unrecognized fragments correctly implements the PR requirement.

Consider deriving tabsToFragmentMap from the tabs array (or vice versa) to avoid maintaining two separate lists that must stay in sync. For now, this is acceptable.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9ae9ce and 22f0d4b.

📒 Files selected for processing (1)
  • src/pages/sponsors/edit-sponsor-page.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build
  • GitHub Check: build
  • GitHub Check: build
🔇 Additional comments (2)
src/pages/sponsors/edit-sponsor-page.js (2)

120-123: LGTM!

Setting window.location.hash correctly updates the URL and adds a browser history entry, enabling back/forward navigation between tabs.


155-155: Formatting change acknowledged.

Minor whitespace adjustment in the sx prop—no functional impact.

@fntechgit fntechgit deleted a comment from coderabbitai bot Jan 12, 2026
Copy link

@smarcet smarcet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niko-exo please review

const result = tabsToFragmentMap.indexOf(
window.location.hash.replace("#", "")
);
return result > -1 ? result : 0;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on the initial load
general tab should be selected hence #general should be show by default

 if (result > -1) return result;

  if (window.location.hash) window.location.hash = "general";
  return 0
```;

const [selectedTab, setSelectedTab] = useState(0);
const [selectedTab, setSelectedTab] = useState(getTabFromUrlFragment());

useEffect(() => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niko-exo
rite now the tab selection only updates from the URL hash on initial page load. The effect useEffect(..., [window.location.hash]) won’t reliably fire on hash updates because changing window.location.hash doesn’t trigger a React re-render.

To support SPA-style hash navigation (manual hash edits, back/forward), please replace that effect with a hashchange listener

@niko-exo niko-exo force-pushed the feature/tab-deep-linking-fragment branch from 22f0d4b to 9c4adf3 Compare January 14, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants